/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use conhash::Node;

use crate::treaty::*;

pub const REPLICAS: usize = 20;

#[derive(Debug, Clone)]
pub struct HashNode<T>
    where
        T: Clone,
{
    data: T,
}

impl<T: Clone> HashNode<T> {
    pub fn new(data: T) -> Self {
        Self { data }
    }
    pub fn data(&self) -> T {
        self.data.clone()
    }
}

impl Node for HashNode<&String> {
    fn name(&self) -> String {
        self.data.into()
    }
}

impl HashNode<Server> {
    pub fn server_type(&self) -> String {
        self.data.server_type.clone()
    }
    pub fn server_id(&self) -> String {
        self.data.server_id.clone()
    }
}

impl Node for HashNode<Server> {
    fn name(&self) -> String {
        format!("{}:{}", self.data.server_name, self.data.server_id)
    }
}

#[cfg(test)]
mod tests {
    use conhash::ConsistentHash;

    use super::*;

    #[test]
    fn treaty_server_test() {
        let mut ch = ConsistentHash::new();
        let nodes = [
            HashNode::new(Server {
                server_type: "a".to_owned(),
                server_id: "a001".to_owned(),
                ..Default::default()
            }),
            HashNode::new(Server {
                server_type: "a".to_owned(),
                server_id: "a002".to_owned(),
                ..Default::default()
            }),
            HashNode::new(Server {
                server_type: "b".to_owned(),
                server_id: "b001".to_owned(),
                ..Default::default()
            }),
        ];
        for node in nodes.iter() {
            ch.add(node, REPLICAS);
        }
        let node = ch.get("28563".as_bytes()).unwrap();
        println!("node is:{:?}", node)
    }
}
